/* proc.h
   By: Teresa Hume
   Date Created: March 7th 2011

   Modified By: Samuel Ferguson
   Date Modified: April 4 2011
*/

#ifndef _XXXOS_PROC_H
#define _XXXOS_PROC_H

#include <memory.h>

/* process states */
#define TASK_RUNNING 0
#define TASK_STOPPED 1
#define TASK_IDLE 2

/* The number of task queues */
#define NUM_QUEUES 3
/* The maximum number of tasks per queue */
#define MAX_TASKS 10

/*********************************/
/*** Typedefs ********************/
/*********************************/

/* a process id is a positive integer */
typedef unsigned int pid_t;

/*********************************/
/*** Structs *********************/
/*********************************/

/*
  the task_struct defines the basic structure of a process
*/
struct task_struct
{
  void *sp; 	/* the stack pointer in user space */
  void *esp0;     /* the kernel stack pointer (where state is stored */

  int state; 	/* TASK_RUNNING or TASK_STOPPED */
  pid_t pid; 	/* id of this process */
  pid_t ppid;     /* the parent's pid */
  
  /* during a context switch) */
  unsigned int quantum; 	/* the quantum for which this process can */
  /* run */
    
  struct mm_struct *mm; /* memory manager struct */
  struct task_struct *next; /* the next runnable process */
};

/* task queues contain nodes */
struct task_node{
  struct task_struct *next;
  struct task_struct *data;
};

/*
  the task queues for processes that are running/blocked/completed
*/
struct task_queue
{
  struct task_node task_queue[MAX_TASKS];
  int curr_tasks;
  int head;
  int tail;
};

/*********************************/
/*** Global Variables ************/
/*********************************/

extern struct task_queue tasks[NUM_QUEUES];
extern struct task_struct* current;

extern void* current_kstack;
extern void* current_pstack;

/*********************************/
/*** Functions *******************/
/*********************************/

void printCurrEsp();
struct task_struct* getCurrentTask();
void setCurrentTask(struct task_struct* new_task);

/*
 * init_task :: struct task_struct x int x pid_t x pid_t x void* x 
 * void* x int x struct mm_struct -> int
 *
 * init task sets up all of the task fields for a new task_struct
 * 
 * returns 0 on success, -1 otherwise
 */
int init_task(struct task_struct* task, int state, pid_t pid, 
	      pid_t ppid, struct mm_struct* mm, void (*code_ptr)());

/*
 * init_task_queue :: void -> int
 *
 * function that takes in a pointer to a task_queue and initializes
 * its values
 *
 * returns 0 on success, -1 otherwise
 */
int init_task_queues(void);

/*
 * enqueue_task :: struct task_struct -> int
 *
 * function that takes a task and puts the task on
 * the appropriate queue based on the task->state
 *
 * returns 0 on success, -1 if full, -2 if invalid
 */
int enqueue_task(struct task_struct* task);

/*
 * dequeue_task :: struct task_struct x int -> int
 *
 * function that dequeues the next task in the appropriate task_queue
 * based on the queue id and copies it to task
 *
 * returns 0 on success, -1 otherwise
 */
int dequeue_task(struct task_struct** task, int queue_id);

/* debugging function for printing a task_struct */
void printTask(struct task_struct* task);
/* debugging functions for printing global variables */
void printCurrEsp();
void print_running_queue();

#endif /* _XXXOS_PROC_H */

